/**
 * Alibaba.com.cn Inc.
 * Copyright (c) 2004-2021 All Rights Reserved.
 */
package com.starlink.common.strategy.paynotify;

import com.starlink.common.enums.OrderRefundEnum;
import com.starlink.common.enums.OrderTypeEnum;
import com.starlink.common.strategy.IPayNotify;
import com.starlink.mapper.MallRefundsMapper;
import com.starlink.model.domain.*;
import com.starlink.model.request.MallPaymentRequest;
import com.starlink.model.request.MallRefundPriceRequest;
import com.starlink.model.request.PointsAcquireBillRequest;
import com.starlink.model.request.PointsUseBillRequest;
import com.starlink.model.request.mall.WechatPay;
import com.starlink.model.request.mall.WechatRefund;
import com.starlink.service.*;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import static com.starlink.common.enums.AcquireModeEnum.POINT_XIAO_FEI;
import static com.starlink.common.enums.AcquireModeEnum.TUI_KUAN;
import static com.starlink.common.enums.ActionTypeEum.INTEGRATION_CANCEL;
import static com.starlink.common.enums.ActionTypeEum.POINTS_EXCHANGE;
import static com.starlink.common.enums.BooleanEnum.TRUE;
import static com.starlink.common.enums.OperationTypeEnum.ADMIN_REFUND_PRICE;
import static com.starlink.common.enums.OrderStatusEnum.*;

/**
 * @author zhanghong
 * @version IntegralPayNotify.java, v 0.1 2024/4/11 23:02 下午 IntegralPayNotify Exp $$
 */
@Component
public class IntegralPayNotify implements IPayNotify {
    @Autowired
    private PointsService pointsService;
    @Autowired
    private MallIntegrationService integrationService;
    @Autowired
    private MallIntegrationOrderService integrationOrderService;
    @Autowired
    private MallPaymentService paymentService;

    @Autowired
    private MallRefundPriceService refundPriceService;
    @Autowired
    private MallRefundsMapper refundsMapper;

    @Override
    public boolean supports(Integer orderType) {
        return orderType.equals(OrderTypeEnum.INTEGRAL.getType());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handle(WechatPay wechatPay) {
        Long userId = wechatPay.getUserId();
        Long integralPrice = wechatPay.getIntegralPrice();
        Long orderId = Long.valueOf(wechatPay.getOrderId());
        String weChatOrderId = wechatPay.getWeChatOrderId();
        String payType = wechatPay.getPayType();
        String amount = wechatPay.getAmount();
        Date paymentDate = wechatPay.getPaymentDate();
        //扣除积分
        PointsUseBillRequest billRequest = new PointsUseBillRequest();
        billRequest.setUserId(userId);
        billRequest.setTitle(POINTS_EXCHANGE.getType());
        billRequest.setConsumeMode(POINT_XIAO_FEI.getType());
        billRequest.setConsumePonts(integralPrice.intValue());
        pointsService.consumPoint(billRequest);
        //修改订单状态
        MallIntegrationOrderDO orderDO = integrationOrderService.lambdaQuery().eq(MallIntegrationOrderDO::getId, orderId).one();
        if (!WAIT_FREE.getType().equals(orderDO.getStatus())) {
            integrationOrderService.lambdaUpdate()
                    .set(MallIntegrationOrderDO::getStatus, WAIT_FREE.getType().toString())
                    .eq(MallIntegrationOrderDO::getId, orderId)
                    .update();
        }
        //添加支付记录
        List<MallPaymentDO> list = paymentService.lambdaQuery().eq(MallPaymentDO::getOrderId, orderId).last("for update").list();
        if (CollectionUtils.isEmpty(list)) {
            MallPaymentRequest mallPaymentRequest = new MallPaymentRequest();
            mallPaymentRequest.setOrderId(orderId);
            mallPaymentRequest.setWxOrderNum(weChatOrderId);
            mallPaymentRequest.setPaymentDate(paymentDate);
            mallPaymentRequest.setPaymentMethod(payType);
            mallPaymentRequest.setAmount(new BigDecimal(amount));
            paymentService.add(mallPaymentRequest);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void refundHandle(WechatRefund wechatPay) {
        Long orderId = wechatPay.getOrderId();
        Integer operationType = wechatPay.getOperationType();
        Long userId = wechatPay.getUserId();
        String orderNum = wechatPay.getOrderNum();
        MallIntegrationOrderDO integrationOrderDO = integrationOrderService.lambdaQuery()
                .eq(MallIntegrationOrderDO::getId, orderId)
                .one();
        //恢复库存
        MallIntegrationDO integrationDO = integrationService.lambdaQuery()
                .eq(MallIntegrationDO::getId, integrationOrderDO.getMallIntegrationId())
                .last("FOR UPDATE")
                .one();
        integrationService.lambdaUpdate()
                .set(MallIntegrationDO::getSurplusInventory,integrationOrderDO.getQuantity()+integrationDO.getSurplusInventory())
                .eq(MallIntegrationDO::getId,integrationOrderDO.getMallIntegrationId())
                .update();
        Long integralPrice = integrationOrderDO.getIntegralPrice();
        if (integralPrice!=null && integralPrice>0L){
            //退还积分
            PointsAcquireBillRequest billRequest = new PointsAcquireBillRequest();
            billRequest.setUserId(integrationOrderDO.getUserId());
            billRequest.setTitle(INTEGRATION_CANCEL.getType());
            billRequest.setAcquireMode(TUI_KUAN.getType());
            billRequest.setAcquirePoint(integrationOrderDO.getIntegralPrice().intValue());
            pointsService.addPoint(billRequest);
        }
        //修改状态
        MallRefundPriceRequest priceRequest = new MallRefundPriceRequest();
        if (ADMIN_REFUND_PRICE.getType().equals(operationType)) {
            Long refundId = refundsMapper.selectIdByOrderId(wechatPay.getOrderId());
            priceRequest.setRefundId(refundId);
            //修改订单状态
            integrationOrderService.lambdaUpdate()
                    .set(MallIntegrationOrderDO::getStatus, BEFOR_SALE.getType().toString())
                    .set(MallIntegrationOrderDO::getUpdateTime, new Date())
                    .set(MallIntegrationOrderDO::getIsRefunds,TRUE.getCode())
                    .set(MallIntegrationOrderDO::getCancelTime,new Date())
                    .eq(MallIntegrationOrderDO::getId, orderId)
                    .update();
            //修改售后状态
            MallRefundsDO refundsDO = new MallRefundsDO();
            refundsDO.setOrderId(orderId);
            refundsDO.setStatus(OrderRefundEnum.WAN_CHENG.getType());
            refundsDO.setAdminId(userId);
            refundsDO.setUpdateTime(new Date());
            refundsDO.setUpdateUser(userId);
            refundsMapper.updateByOrderId(refundsDO);
        }else {
            //修改订单状态
            integrationOrderService.lambdaUpdate()
                    .set(MallIntegrationOrderDO::getStatus, CANCEL.getType().toString())
                    .set(MallIntegrationOrderDO::getUpdateTime, new Date())
                    .eq(MallIntegrationOrderDO::getId, orderId)
                    .update();
        }
        //添加退款记录
        priceRequest.setRefundNum(wechatPay.getRefundNum());
        priceRequest.setWxRefundNum(wechatPay.getWxRefundNum());
        priceRequest.setOrderNum(wechatPay.getOrderNum());
        priceRequest.setRefundPrice(new BigDecimal(wechatPay.getAmount()));
        priceRequest.setRefundType(wechatPay.getRefundType());
        priceRequest.setRefundTime(new Date());
        priceRequest.setCreateTime(new Date());
        priceRequest.setCreateUser(userId);
        Integer count =  refundPriceService.selectCountByOrderId(orderNum);
        if (count==0){
            refundPriceService.add(priceRequest);
        }
    }
}
